feat: add webapi response changes as of 2026-08-07 - #1629
Conversation
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #1629 +/- ##
============================================
- Coverage 73.34% 73.24% -0.10%
+ Complexity 4528 4522 -6
============================================
Files 478 478
Lines 14314 14314
Branches 1491 1491
============================================
- Hits 10498 10484 -14
- Misses 2924 2940 +16
+ Partials 892 890 -2
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. |
ActionsResponse.Actions: List<String> workObjectRecord SchemasResponse: WorkObjectRecord class (id, appId, objectId, objectType) Actions: WorkObjectRecord inner class with enterprise_search_email_attachment_downloaded Additive, no breaking changes; verified against the live audit API response. ❤️ Co-Authored-By: Claude <svc-devxp-claude@slack-corp.com>
rtmConnect(token) requests full user info, adding a users.info call between rtm.connect and the websocket. That second HTTPS request may or may not reuse the pooled proxy tunnel, so the proxy occasionally sees a third CONNECT and the callCount assertion flakes between 2 and 3. The test does not use the connected user info, so request it without the extra call to keep the count deterministic at 2. ❤️ Co-Authored-By: Claude <svc-devxp-claude@slack-corp.com>
| // fullUserInfoRequired=false: skip the extra users.info call so the proxy sees exactly | ||
| // two connections (rtm.connect + websocket), otherwise a third tunnel can be opened | ||
| try (RTMClient rtm = slack.rtmConnect(rtmBotToken, false)) { // slack-msgs.com |
There was a problem hiding this comment.
💡 note: Added to reduce flakes of scheduled tests! We now hope to focus on new properties with the test runner.
Detected as a new audit action by the E2E runner (Unknown action detected). Adds the constant alongside the other mcp_slack_*_tool_called entries. ❤️ Co-Authored-By: Claude <svc-devxp-claude@slack-corp.com>
…tured.list Assert the success-only `message` field on chat.stopStream, and rewrite the workflows.featured.list E2E test to a real add -> list -> assert -> remove flow (resolving a real channel and reading a trigger id from SLACK_SDK_TEST_WORKFLOW_TRIGGER_ID, no-op when unset) so the sample recorder captures featured_workflows. Error-only tests only ever recorded the base error shape, leaving the generated response types thin. ❤️ Co-Authored-By: Claude <svc-devxp-claude@slack-corp.com>
Use JUnit Assume instead of an early return so the test reports as skipped (not a silent pass) when SLACK_SDK_TEST_WORKFLOW_TRIGGER_ID or a resolvable channel is absent. A bare return counted the test as passed while recording nothing, hiding that the featured_workflows sample never got captured. ❤️ Co-Authored-By: Claude <svc-devxp-claude@slack-corp.com>
workflows.featured.list resolved an arbitrary channel (first in the list), which returned restricted_action from featuredAdd. Target the workspace #general channel instead, matching how files_Test resolves it, and skip when it isn't found. ❤️ Co-Authored-By: Claude <svc-devxp-claude@slack-corp.com>
workflows.featured.add/set/remove require a caller with permission to
manage workflows in the target channel. A bot token is denied with
"restricted_action" even when it holds workflows.templates:write and is
a channel member, so the add->list->assert->remove flow must run on the
user token. Reproduced across four channels; user token succeeds and
list returns the full featured_workflows[].triggers[].{id,title} shape.
Skips honestly when SLACK_SDK_TEST_USER_TOKEN is unset.
❤️
Co-Authored-By: Claude <svc-devxp-claude@slack-corp.com>
pins.list nests the pinned message as a top-level com.slack.api.model.Message, and the response now carries a permalink URL string that the top-level class did not model (permalink existed only on the MessageItem inner class). Under strict unknown-property detection this surfaced as "Unknown property detected: permalink (com.slack.api.model.Message)". ❤️ Co-Authored-By: Claude <svc-devxp-claude@slack-corp.com>
…low test findChannelId listed channels with the bot token and a single limit(100) request, so it could miss #general (page truncation) or return one the user token cannot feature in — tripping the Assume gate and silently skipping the featured-workflow flow. List from the user token (the acting identity) and page through next_cursor so the test actually runs and records the featured_workflows shape. ❤️ Co-Authored-By: Claude <svc-devxp-claude@slack-corp.com>
serialize(File) called context.serialize(src), which re-dispatched to this same registered adapter and recursed until StackOverflowError. That crashed SampleObjects.Json static init, which in turn aborted json-log sample recording for any response containing a nested Message (e.g. chat.stopStream), silently dropping fields like `message` from the generated samples. Serialize as the NormalizedFile subclass (no registered adapter, default reflective serializer), mirroring the existing deserialize() workaround. ❤️ Co-Authored-By: Claude <svc-devxp-claude@slack-corp.com>
zimeg
left a comment
There was a problem hiding this comment.
📣 Leaving notes on changes to the test runner itself that might be worth more consideration!
I'm eager to land the additions to response for handfuls of method for improved typescript usage downstream!
| @Override | ||
| public JsonElement serialize(File src, Type typeOfSrc, JsonSerializationContext context) { | ||
| return context.serialize(src); | ||
| // To prevent StackOverflowError here, serialize as File's subclass (see deserialize above). | ||
| return context.serialize(src, NormalizedFile.class); | ||
| } | ||
| } |
There was a problem hiding this comment.
🗣️ note: We workaround the errors of serialization that caused various message properties to be missing due to infinite recursion using the same "NormalizedFile" class technique above.
| ).get(); | ||
| assertThat(workflowsFeaturedListResponse.getError(), is(notNullValue())); | ||
| public void workflowsFeaturedList() throws Exception { | ||
| String triggerId = System.getenv(Constants.SLACK_SDK_TEST_WORKFLOW_TRIGGER_ID); |
There was a problem hiding this comment.
👁️🗨️ note: We build confidence in responses of workflows.featured.* using a user token and "general" channel ID with existing workflow values.
| )); | ||
| assertThat(stops.isOk(), is(true)); | ||
| assertThat(stops.getError(), is(nullValue())); | ||
| assertThat(stops.getMessage(), is(notNullValue())); |
There was a problem hiding this comment.
👾 note: This adds confidence that the streamed message values are returned and detected as expected here!
| public static final String SLACK_SDK_TEST_CLASSIC_APP_BOT_TOKEN = "SLACK_SDK_TEST_CLASSIC_APP_BOT_TOKEN"; | ||
|
|
||
| // featured workflows tests | ||
| public static final String SLACK_SDK_TEST_WORKFLOW_TRIGGER_ID = "SLACK_SDK_TEST_WORKFLOW_TRIGGER_ID"; |
There was a problem hiding this comment.
🏁 note: An adjacent variable is used with the entire trigger URL but isn't defined in these constants at this time. A follow up PR plans to document this to latest standards our runner uses!
admin.apps.activities.list responses now include provider_key on the activity payload (observed value "mcp_dcr_notion"), which strict unknown-property detection flagged as "Unknown property detected: provider_key (com.slack.api.model.admin.AppActivity$Payload)". ❤️ Co-Authored-By: Claude <svc-devxp-claude@slack-corp.com>
This PR updates the web API client and model based on the production E2E test results.
Category
Requirements
Please read the Contributing guidelines and Code of Conduct before creating this issue or pull request. By submitting, you agree to those rules.